package io.terminus.lego.shinda.web.security.oauth

import com.nimbusds.jose.util.JSONObjectUtils
import com.nimbusds.oauth2.sdk.http.HTTPRequest
import com.nimbusds.oauth2.sdk.util.URLUtils
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import net.minidev.json.JSONObject
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.net.URL
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * 由于国内的一些社交平台使用的并不是Spring-security-oauth2.0约定的bearer认证方式，
 * 因此做一层代理，由proxy进行双向适配，从而满足spring-security-oauth2.0约定的规范
 * 如果需要接入其他社交可用这种方式拓展
 * @author wangmeng
 * @date 2018/4/21
 */
@Api(value = "第三方登录代理服务", description = "由于国内的一些社交平台使用的并不是Spring-security-oauth2.0约定的bearer认证方式" +
        "因此做一层代理，由proxy进行双向适配，从而满足spring-security-oauth2.0约定的规范,这样将规范统一便于接入")
@RestController
@RequestMapping("api/proxy")
class ProxyEndPoint {
    /**
     * 获取微博的access_token
     */
    @ApiOperation("代理-微博access_token接口")
    @RequestMapping("/weibo/access-token")
    fun weibo(request: HttpServletRequest, response: HttpServletResponse): JSONObject {
        //获取微博Access_token
        val proxyRequest = HTTPRequest(HTTPRequest.Method.POST, URL("https://api.weibo.com/oauth2/access_token"))
        val params = proxyRequest.queryParameters
        request.parameterNames.toList().forEach {
            params.put(it, request.getParameter(it))
        }
        //配置请求
        configRequest(proxyRequest, params)
        proxyRequest.readTimeout = 30000
        val httpResponse = proxyRequest.send()
        val content = httpResponse.contentAsJSONObject
        content.put("token_type", "bearer")
        return content
    }

    /**
     * 获取微博用户信息
     */
    @ApiOperation("代理-微博user_info接口")
    @RequestMapping("/weibo/info")
    fun weiboInfo(request: HttpServletRequest, response: HttpServletResponse): JSONObject {
        //从请求头中获取access_token
        val authorization = request.getHeader("Authorization")
        val token = authorization.replace("Bearer", "").trim()
        //获取微博uid
        val uidRequest = HTTPRequest(HTTPRequest.Method.GET, URL("https://api.weibo.com/2/account/get_uid.json"))
        val params = uidRequest.queryParameters
        params.put("access_token", token)
        //配置请求
        configRequest(uidRequest, params)

        val uid = uidRequest.send().contentAsJSONObject["uid"].toString()

        //获取微博用户信息
        val userRequest = HTTPRequest(HTTPRequest.Method.GET, URL("https://api.weibo.com/2/users/show.json"))
        val userParams = userRequest.queryParameters
        userParams.put("access_token", token)
        userParams.put("uid", uid)
        //配置请求
        configRequest(userRequest, userParams)
        val content = userRequest.send().contentAsJSONObject
        return content
    }

    /**
     * 获取QQ的access_token
     */
    @ApiOperation("代理-QQ的access_token接口")
    @RequestMapping("/qq/access-token")
    fun qq(request: HttpServletRequest, response: HttpServletResponse): Map<String, String> {
        //获取参数
        val proxyRequest = HTTPRequest(HTTPRequest.Method.POST, URL("https://graph.qq.com/oauth2.0/token"))
        val params = proxyRequest.queryParameters
        request.parameterNames.toList().forEach {
            params.put(it, request.getParameter(it))
        }
        //配置请求
        configRequest(proxyRequest, params)
        val httpResponse = proxyRequest.send()
        val content = URLUtils.parseParameters(httpResponse.content)
        content.put("token_type", "bearer")
        return content
    }

    /**
     * 获取QQ的用户信息,获取unionid是需要申请的默认不反回
     */
    @ApiOperation("代理-QQ的user_info接口")
    @RequestMapping("/qq/info")
    fun qqInfo(request: HttpServletRequest, response: HttpServletResponse): JSONObject {
        //从请求头中获取access_token
        val authorization = request.getHeader("Authorization")
        val token = authorization.replace("Bearer", "").trim()
        //获取OpenId和oauth_consumer_key
        val uidRequest = HTTPRequest(HTTPRequest.Method.GET, URL("https://graph.qq.com/oauth2.0/me"))
        val params = uidRequest.queryParameters
        params.put("access_token", token)
//        params.put("unionid", "1")
        //配置请求
        configRequest(uidRequest, params)
        val body = uidRequest.send().content
        val jsonString = body.substring(body.indexOf("{"), body.indexOf("}") + 1)
        val contentObject = JSONObjectUtils.parse(jsonString)
        val openid = contentObject["openid"].toString()
        val consumerKey = contentObject["client_id"].toString()
        //获取用户信息
        val userRequest = HTTPRequest(HTTPRequest.Method.GET, URL("https://graph.qq.com/user/get_user_info"))
        val userParams = userRequest.queryParameters
        userParams.put("access_token", token)
        userParams.put("openid", openid)
        userParams.put("oauth_consumer_key", consumerKey)
        //配置请求
        configRequest(userRequest, userParams)
        val content = JSONObjectUtils.parse(userRequest.send().content)
        content.put("openid", openid)
        return content
    }

    private fun configRequest(userRequest: HTTPRequest, userParams: Map<String, String>?) {
        userRequest.query = URLUtils.serializeParameters(userParams)
        userRequest.accept = MediaType.APPLICATION_JSON_VALUE
        userRequest.connectTimeout = 30000
        userRequest.readTimeout = 30000
    }


}